/**
 * 
 */
package net.penguinmenac3.math;

import net.penguinmenac3.math.rings.ComplexNumber;
import net.penguinmenac3.math.rings.RealNumber;

/**
 * @author michael
 * 
 */
public class Benchmark {
	public static void main(String[] args) {
		int iterations = 1000000;
		if (args != null && args.length == 1) {
			iterations = Integer.parseInt(args[0]);
		}
		System.out.println("Benchmark");
		System.out.println("RealNumber - NormalMatrix");
		realNormal(iterations);
		System.out.println("RealNumber - ExtendedMatrix");
		realInverse(iterations);
		System.out.println("ComplexNumber - NormalMatrix");
		complexNormal(iterations);
		System.out.println("ComplexNumber - ExtendedMatrix");
		complexInverse(iterations);
	}

	public static void realNormal(int iterations) {
		long time = 0;

		for (int i = 0; i < iterations; i++) {
			RealNumber[][] m = {
					{ new RealNumber((Math.random() * 101) - 50),
							new RealNumber((Math.random() * 101) - 50),
							new RealNumber((Math.random() * 101) - 50) },
					{ new RealNumber((Math.random() * 101) - 50),
							new RealNumber((Math.random() * 101) - 50),
							new RealNumber((Math.random() * 101) - 50) },
					{ new RealNumber((Math.random() * 101) - 50),
							new RealNumber((Math.random() * 101) - 50),
							new RealNumber((Math.random() * 101) - 50) } };
			Matrix matrix = new Matrix(m);
			Gausian g = new Gausian(matrix);

			long start = System.nanoTime();
			matrix = g.solve(0, false);
			time += (System.nanoTime() - start);
		}

		String timeString = String.format("%.2f", time / 1000000.0);

		System.out.println(iterations + " - " + timeString + "ms");
	}

	public static void realInverse(int iterations) {
		long time = 0;

		for (int i = 0; i < iterations; i++) {
			RealNumber[][] m = {
					{ new RealNumber((Math.random() * 101) - 50),
							new RealNumber((Math.random() * 101) - 50),
							new RealNumber((Math.random() * 101) - 50) },
					{ new RealNumber((Math.random() * 101) - 50),
							new RealNumber((Math.random() * 101) - 50),
							new RealNumber((Math.random() * 101) - 50) },
					{ new RealNumber((Math.random() * 101) - 50),
							new RealNumber((Math.random() * 101) - 50),
							new RealNumber((Math.random() * 101) - 50) } };
			RealNumber[][] e = {
					{ new RealNumber((Math.random() * 101) - 50),
							new RealNumber((Math.random() * 101) - 50),
							new RealNumber((Math.random() * 101) - 50) },
					{ new RealNumber((Math.random() * 101) - 50),
							new RealNumber((Math.random() * 101) - 50),
							new RealNumber((Math.random() * 101) - 50) },
					{ new RealNumber((Math.random() * 101) - 50),
							new RealNumber((Math.random() * 101) - 50),
							new RealNumber((Math.random() * 101) - 50) } };

			Matrix matrix = new ExtendedMatrix(m, e);
			Gausian g = new Gausian(matrix);

			long start = System.nanoTime();
			matrix = g.solve(0, false);
			time += (System.nanoTime() - start);
		}

		String timeString = String.format("%.2f", time / 1000000.0);

		System.out.println(iterations + " - " + timeString + "ms");
	}
	
	public static void complexNormal(int iterations) {
		long time = 0;

		for (int i = 0; i < iterations; i++) {
			ComplexNumber[][] m = {
					{ new ComplexNumber((Math.random() * 101) - 50),
							new ComplexNumber((Math.random() * 101) - 50),
							new ComplexNumber((Math.random() * 101) - 50) },
					{ new ComplexNumber((Math.random() * 101) - 50),
							new ComplexNumber((Math.random() * 101) - 50),
							new ComplexNumber((Math.random() * 101) - 50) },
					{ new ComplexNumber((Math.random() * 101) - 50),
							new ComplexNumber((Math.random() * 101) - 50),
							new ComplexNumber((Math.random() * 101) - 50) } };
			Matrix matrix = new Matrix(m);
			Gausian g = new Gausian(matrix);

			long start = System.nanoTime();
			matrix = g.solve(0, false);
			time += (System.nanoTime() - start);
		}

		String timeString = String.format("%.2f", time / 1000000.0);

		System.out.println(iterations + " - " + timeString + "ms");
	}

	public static void complexInverse(int iterations) {
		long time = 0;

		for (int i = 0; i < iterations; i++) {
			ComplexNumber[][] m = {
					{ new ComplexNumber((Math.random() * 101) - 50),
							new ComplexNumber((Math.random() * 101) - 50),
							new ComplexNumber((Math.random() * 101) - 50) },
					{ new ComplexNumber((Math.random() * 101) - 50),
							new ComplexNumber((Math.random() * 101) - 50),
							new ComplexNumber((Math.random() * 101) - 50) },
					{ new ComplexNumber((Math.random() * 101) - 50),
							new ComplexNumber((Math.random() * 101) - 50),
							new ComplexNumber((Math.random() * 101) - 50) } };
			ComplexNumber[][] e = {
					{ new ComplexNumber((Math.random() * 101) - 50),
							new ComplexNumber((Math.random() * 101) - 50),
							new ComplexNumber((Math.random() * 101) - 50) },
					{ new ComplexNumber((Math.random() * 101) - 50),
							new ComplexNumber((Math.random() * 101) - 50),
							new ComplexNumber((Math.random() * 101) - 50) },
					{ new ComplexNumber((Math.random() * 101) - 50),
							new ComplexNumber((Math.random() * 101) - 50),
							new ComplexNumber((Math.random() * 101) - 50) } };

			Matrix matrix = new ExtendedMatrix(m, e);
			Gausian g = new Gausian(matrix);

			long start = System.nanoTime();
			matrix = g.solve(0, false);
			time += (System.nanoTime() - start);
		}

		String timeString = String.format("%.2f", time / 1000000.0);

		System.out.println(iterations + " - " + timeString + "ms");
	}
}
